flush(stdout); println("Start execution of tax-inv-release.jl")

using Optim
using FiniteDiff

include("Vert.jl")

# define a market object
# define an equilibrium object
# given a market, solve for the equilibrium

# calibrate using the moments.

testMkt = Vert.Market(
    449.4767002,
    1.1689,
    0.51887998,
    0.0,
    0.51887998,
    0.01,
    0.923158069,
    0.01,
    0.923158069,
    0.0,
    0.32,
    0.0,
    0.0,
    0.0,
    0.0,
    0.0,
    0.37
)

eq = Vert.SolveEquilibrium(testMkt)
println("the equilibrium is $(exp.(Optim.minimizer(eq)))")


println("Testing moment conditions")

x = [0.11064573572331748, 0.06160214482610775, 0.11883673505737861, 0.04677785902628812, 0.04167941277424804, 1.0]

mkt_prereform = Vert.Market(449.4767002, 1.1689, 0.0, x[1], 0.0, x[2], 0.0, x[3], 0.0, x[4], 0.0, x[5], x[5], x[6], 0.25, 0.25, 0.25)

moments = Vert.CalculateCalibrationMoments(x; debug=true)

println(moments)


println("Calibration.")
function CalObj(x)
    comp = [0.955, 3.60, 1.53, 0.53746325, 0.41334113, 9.39]
    y = exp.(x)
    y[5] = y[5]/(1+y[5])
    y[6] = y[6]/(1+y[6])
    out = Vert.CalculateCalibrationMoments(y)
    diff = comp .- out
    weights = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
    result = sum(diff .* diff .* weights)
    return result
end

start = log.([.1106, .0616, .1188, .0468, 0.25, 0.25])
println(CalObj(start))
result = optimize(CalObj, start, ConjugateGradient())

min = Optim.minimum(result)

params = deepcopy(Optim.minimizer(result))
params = exp.(params)
params[5] = params[5]/(1+params[5])
params[6] = params[6]/(1+params[6])

println("Calibrated: $params")
println("Moments: $min @ $(Vert.CalculateCalibrationMoments(params))")

# figure out outcomes pre and post
x = params
mkt_pre = Vert.Market(449.4767002, 1.1689, 0.0, x[1], 0.0, x[2], 0.0, x[3], 0.0, x[4], 0.0, x[5], x[5], x[6], 0.25, 0.25, 0.25)
mkt_post = Vert.Market(449.4767002, 1.1689, 0.0, x[1], 0.0, x[2], 0.0, x[3], 0.0, x[4], 0.0, x[5], x[5], x[6], 0.0, 0.0, 0.37+0.0693)
mkt_post2 = Vert.Market(449.4767002, 1.1689, 0.0, x[1], 0.0, x[2], 0.0, x[3], 0.0, x[4], 0.0, x[5], x[5], x[6], 0.0, 0.0, 0.25+0.0693)


res_pre = Vert.SolveEquilibrium(mkt_pre)
res_post = Vert.SolveEquilibrium(mkt_post)
res_post2 = Vert.SolveEquilibrium(mkt_post2)

out_pre = Vert.Choices(exp.(Optim.minimizer(res_pre))...)
out_post = Vert.Choices(exp.(Optim.minimizer(res_post))...)
out_post2 = Vert.Choices(exp.(Optim.minimizer(res_post2))...)

println("Pre-reform: $out_pre")
println("Post-reform: $out_post")
println("Post-reform v2: $out_post2")

println("Pre-conditions: $(Vert.EvaluateMarketConditions(out_pre, mkt_pre))")
println("Post-conditions: $(Vert.EvaluateMarketConditions(out_post, mkt_post))")
println("Post-conditions v2: $(Vert.EvaluateMarketConditions(out_post2, mkt_post2))")



println("Done.")